import datetime
import os
import threading
import time

import cv2
import requests

import metric
import mqtt
from logger import log
from settings import settings


class CameraCheck:

    def check_camera_from_rtsp(self, stream_url):
        cap = None
        try:
            os.environ["OPENCV_FFMPEG_CAPTURE_OPTIONS"] = "timeout;5000|rtsp_transport;udp"
            cap = cv2.VideoCapture(stream_url, cv2.CAP_FFMPEG)
            # cap = cv2.VideoCapture(stream_url)
            if hasattr(cv2, 'CAP_PROP_OPEN_TIMEOUT_MSEC'):
                cap.set(cv2.CAP_PROP_OPEN_TIMEOUT_MSEC, 5000)
            if hasattr(cv2, 'CAP_PROP_READ_TIMEOUT_MSEC'):
                cap.set(cv2.CAP_PROP_READ_TIMEOUT_MSEC, 5000)
            if not cap.isOpened():
                log.info(f"check_camera_from_rtsp not cap.isOpened() url={stream_url}")
                return False
            else:
                return True
        except Exception as e:
            log.exception(e)
            return False
        finally:
            # 确保释放资源
            if cap is not None and cap.isOpened():
                cap.release()

    def capture_logic(self, start=False):
        while True:
            try:
                # 获取当前时间
                current_time = datetime.datetime.now()
                if current_time.minute % 5 == 0 or start:
                    log.info("Test camera... current_time:{}".format(current_time))
                    for item in settings.streams:
                        stream_id = item['id']
                        online = True
                        stream_url = item['rtsp']
                        camera_check_result_success = self.check_camera_from_rtsp(stream_url)
                        log.info(f"{item['name']},{stream_id} camera_check_result:{camera_check_result_success}")
                        if not camera_check_result_success:
                            online = False
                            date = current_time
                            full_year = metric.get_date_str(date)
                            content = {
                                "deviceName": settings.code,
                                "cameraName": item['name'],
                                "platformName": settings.platformName
                            }
                            metric.send("vsNode", content, "cameraOffline", int(full_year))
                            mqtt.add_offline_camera(item['name'], item['rtsp'])
                        else:
                            mqtt.remove_offline_camera(item['name'])
                        # 更新摄像头在线状态
                        log.info(f"{stream_id} online:{online}")
                        self.update_stream_online(stream_id, online)
                # 短暂睡眠减少循环频率
                time.sleep(60)
            except Exception as e:
                log.exception(e)

    def update_stream_online(self, stream_id, online):
        try:
            data = {
                "id": stream_id,
                "online": online
            }
            resp = requests.post("https://" + settings.host + "/api/weigh/internal/vsStream/online", json=data)
            if resp.status_code == 200:
                log.info(f"Updated stream success {resp.json()}")
            else:
                log.error(f"Updated stream error {resp.status_code}")
        except Exception as e:
            log.exception(e)

    # 定时任务
    def init(self):
        thread = threading.Thread(target=self.capture_logic)
        thread.start()


camera_check = CameraCheck()

if __name__ == '__main__':
    log.info("Starting camera_check...")
    settings.init(code="xhg_vs1", host="platform.hbsmwljt.com", force_codec="video/H264")
    camera_check.capture_logic(start=True)
